#ifndef __STORMWIDGET_STORMWIDGET_BASECLASSLIBRARY_AUTO_PTR_H
#define __STORMWIDGET_STORMWIDGET_BASECLASSLIBRARY_AUTO_PTR_H
namespace bcl
{
	template<class _Tp1>
	struct auto_ptr_ref
	{
		_Tp1* _M_ptr;
		auto_ptr_ref(_Tp1* __p):_M_ptr(__p){}
	};

	template <class _Tp>
	class auto_ptr
	{
	private:
		_Tp* _M_ptr;
	public:
		typedef _Tp element_type;

		explicit auto_ptr(_Tp* __p = 0):_M_ptr(__p){}
		auto_ptr(auto_ptr& __a):_M_ptr(__a.release()){}

		template <class _Tp1>
		auto_ptr(auto_ptr<_Tp1>& __a):_M_ptr(__a.release()){}

		auto_ptr& operator= (auto_ptr& __a)
		{
			if(&__a != this)
			{
				delete _M_ptr;
				_M_ptr = __a.release();
			}
			return *this;
		}

		template <class _Tp1>
		auto_ptr& operator= (auto_ptr<_Tp1>& __a)
		{
			if(__a.get() != this->get())
			{
				delete _M_ptr;
				_M_ptr = __a.release();
			}
			return *this;
		}

		~auto_ptr() { delete _M_ptr; }

		_Tp& operator*() const
		{
			return *_M_ptr;
		}

		_Tp* operator->() const
		{
			return _M_ptr;
		}

		_Tp* get() const
		{
			return _M_ptr;
		}

		_Tp* release()
		{
			_Tp* __tmp = _M_ptr;
			_M_ptr = 0;
			return __tmp;
		}

		void reset(_Tp* __p = 0)
		{
			if(__p != _M_ptr)
			{
				delete _M_ptr;
				_M_ptr = __p;
			}
		}
	public:
		auto_ptr(auto_ptr_ref<_Tp> __ref):_M_ptr(__ref._M_ptr){}
		auto_ptr& operator= (auto_ptr_ref<_Tp> __ref)
		{
			if(__ref._M_ptr != this->get())
			{
				delete _M_ptr;
				_M_ptr = __ref._M_ptr;
			}
			return *this;
		}

		template <class _Tp1> operator auto_ptr_ref<_Tp1>()
		{
			return auto_ptr_ref<_Tp1>(this->release());
		}

		template <class _Tp1> operator auto_ptr<_Tp1>()
		{
			return auto_ptr<_Tp1>(this->release());
		}
	};
};
#endif //__STORMWIDGET_STORMWIDGET_BASECLASSLIBRARY_AUTO_PTR_H